package main

import (
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"strconv"
	strings "strings"
)

/**
@author luckyFang
@date 2020 10 15
@desc 上传服务handler
*/

// 文件修改
func updateHandler(w http.ResponseWriter, r *http.Request) {
	// 方式验证
	if r.Method != "PUT" {
		OutputJson(w, http.StatusBadRequest, "Wrong way to request!")
		return
	}

	// 验证 key
	key := r.FormValue("key")
	isOk := strings.Compare(key, uploadKey)
	if isOk != 0 {
		OutputJson(w, http.StatusForbidden, "No upload permission!")
		return
	}
	w.Header().Set("content-type", "application/json")
	// 获取文件名称
	filename := r.URL.Path[len("/update/"):]

	// 判断是否是md5 格式
	suffix := filename[strings.Index(filename, ".")+1:]
	filename = filename[:strings.Index(filename, ".")]

	if len(filename) != 32 {
		filename = toMd5(filename+"."+suffix)+"."+suffix
		log.Println(filename)
	}
	// 验证文件是否存在
	if fileExists(uploadPath+"/"+filename) != nil {
		OutputJson(w, http.StatusNotFound, "The file does not exist!")
		return
	}

	// 验证文件
	file, header, err := r.FormFile("file")
	if err != nil {
		OutputJson(w, http.StatusBadRequest, "Bad Request!")
		return
	}
	// 验证大小
	if header.Size > maxSize {
		OutputJson(w, http.StatusBadRequest, "The file length is out of range！")
		return
	}
	dst, err := os.Create(uploadPath + "/" + filename)
	if err != nil {
		// 创建文件失败资源不足
		OutputJson(w, http.StatusInternalServerError, err.Error())
		return
	}
	// 复制文件到指定路径
	_, err = io.Copy(dst, file)
	if err != nil {
		// 复制文件失败 io 拥堵
		OutputJson(w, http.StatusInternalServerError, err.Error())
		return
	}
	// 上传成功 后通知系统回收垃圾
	OutputJson(w, http.StatusOK, "http://"+hostName+":"+strconv.Itoa(port)+"/"+filename)
	runtime.GC()

}

// 文件删除
func deleteHandler(w http.ResponseWriter, r *http.Request) {
	// 方式验证
	if r.Method != "DELETE" {
		OutputJson(w, http.StatusBadRequest, "Wrong way to request!")
		return
	}
	// 验证 key
	key := r.FormValue("key")
	isOk := strings.Compare(key, uploadKey)
	if isOk != 0 {
		OutputJson(w, http.StatusForbidden, "No upload permission!")
		return
	}
	w.Header().Set("content-type", "application/json")
	// 获取文件名称
	filename := r.URL.Path[len("/delete/"):]
	// 验证文件是否存在
	if fileExists(uploadPath+"/"+filename) != nil {
		OutputJson(w, http.StatusNotFound, "The file does not exist!")
		return
	}
	// 删除文件
	err := os.Remove(uploadPath + "/" + filename)
	if err != nil {
		OutputJson(w, http.StatusNotFound, "Failed to delete file!")
		return
	}
	OutputJson(w, http.StatusOK, "File deleted successfully!")
}

// 文件上传
func uploadHandler(w http.ResponseWriter, r *http.Request) {
	// 验证请求方式
	if r.Method != "POST" {
		OutputJson(w, http.StatusBadRequest, "Wrong way to request!")
		return
	}
	// 验证 key
	key := r.FormValue("key")
	isOk := strings.Compare(key, uploadKey)
	if isOk != 0 {
		OutputJson(w, http.StatusForbidden, "No upload permission!")
		return
	}
	w.Header().Set("content-type", "application/json")
	// 验证文件
	file, header, err := r.FormFile("file")
	if err != nil {
		OutputJson(w, http.StatusBadRequest, "Bad Request!")
		return
	}
	// 验证大小
	if header.Size > maxSize {
		OutputJson(w, http.StatusBadRequest, "The file length is out of range！")
		return
	}

	// 获取文件后缀 和 hash
	suffix := header.Filename[strings.Index(header.Filename, ".")+1:]
	md5 := toMd5(header.Filename)
	// 判断文件是否存在
	if fileExists(uploadPath+"/"+md5+"."+suffix) == nil {
		OutputJson(w, http.StatusBadRequest, "The file already exists!")
		return
	}
	dst, err := os.Create(uploadPath + "/" + md5 + "." + suffix)
	if err != nil {
		// 创建文件失败资源不足
		OutputJson(w, http.StatusInternalServerError, err.Error())
		return
	}
	// 复制文件到指定路径
	_, err = io.Copy(dst, file)
	if err != nil {
		// 复制文件失败 io 拥堵
		OutputJson(w, http.StatusInternalServerError, err.Error())
		return
	}
	// 上传成功 后通知系统回收垃圾
	OutputJson(w, http.StatusOK, "http://"+hostName+":"+strconv.Itoa(port)+"/"+md5+"."+suffix)
	runtime.GC()

	// 写入 cookies 存取上传信息
}
